package aftersale

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/common/moneyx"
	"mall/common/resultx"
	"mall/service/backend/common/i18n"
	"mall/service/order/model"
	"mall/service/order/rpc/internal/svc"
	"mall/service/order/rpc/internal/utils/errorhandler"
	"mall/service/order/rpc/types/order"

	"github.com/sirupsen/logrus"
	"github.com/volatiletech/null/v8"
	"github.com/zeromicro/go-zero/core/logx"
)

type CreateAfterSaleLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCreateAfterSaleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateAfterSaleLogic {
	return &CreateAfterSaleLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// group: after_sale
func (l *CreateAfterSaleLogic) CreateAfterSale(in *order.AfterSaleInfo) (*order.BaseIDResp, error) {
	logrus.Info(fmt.Sprintf("CreateAfterSale in: %+v", in))
	if in.UserId == nil || *in.UserId == 0 || in.Mobile == nil || len(strings.TrimSpace(*in.Mobile)) == 0 {
		return nil, resultx.StatusError(resultx.AFTER_SALE_PARAM_INVALID, "")
	}
	if in.OrderId == nil || *in.OrderId == 0 || in.OrderItemId == nil || *in.OrderItemId == 0 || in.OrderSn == nil || len(strings.TrimSpace(*in.OrderSn)) == 0 {
		return nil, resultx.StatusError(resultx.AFTER_SALE_PARAM_INVALID, "")
	}
	if in.ProductId == nil || *in.ProductId == 0 || in.ProductSkuId == nil || *in.ProductSkuId == 0 || in.ProductTitle == nil || len(strings.TrimSpace(*in.ProductTitle)) == 0 {
		return nil, resultx.StatusError(resultx.AFTER_SALE_PARAM_INVALID, "")
	}
	if in.AfterSaleType == nil || *in.AfterSaleType == 0 || in.AfterSaleSn == nil || len(strings.TrimSpace(*in.AfterSaleSn)) == 0 || in.Status == nil || *in.Status == 0 {
		return nil, resultx.StatusError(resultx.AFTER_SALE_PARAM_INVALID, "")
	}
	var afterSaleRequest model.AfterSaleRequest
	afterSaleRequest.AfterSalesSN = *in.AfterSaleSn
	afterSaleRequest.OrderID = *in.OrderId
	afterSaleRequest.OrderItemID = *in.OrderItemId
	afterSaleRequest.OrderSN = *in.OrderSn
	afterSaleRequest.ProductID = *in.ProductId
	afterSaleRequest.ProductSkuID = *in.ProductSkuId
	afterSaleRequest.ProductTitle = *in.ProductTitle
	afterSaleRequest.UserID = *in.UserId
	afterSaleRequest.Mobile = *in.Mobile
	afterSaleRequest.Status = uint8(*in.Status)
	afterSaleRequest.AfterSaleType = uint8(*in.AfterSaleType)
	if in.ProductCode != nil && len(strings.TrimSpace(*in.ProductCode)) > 0 {
		afterSaleRequest.ProductCode = *in.ProductCode
	}
	if in.ProductSku != nil && len(strings.TrimSpace(*in.ProductSku)) > 0 {
		afterSaleRequest.ProductSku = *in.ProductSku
	}
	if in.ProductSkuCode != nil && len(strings.TrimSpace(*in.ProductSkuCode)) > 0 {
		afterSaleRequest.ProductSkuCode = *in.ProductSkuCode
	}
	if in.SkuThumbUrl != nil && len(strings.TrimSpace(*in.SkuThumbUrl)) > 0 {
		afterSaleRequest.SkuImageURL = *in.SkuThumbUrl
	}
	if in.ProductPrice != nil && *in.ProductPrice > 0 {
		afterSaleRequest.ProductPrice = *in.ProductPrice
	}
	if in.Quantity != nil && *in.Quantity > 0 {
		afterSaleRequest.Quantity = uint64(*in.Quantity)
	}
	if in.NickName != nil && len(strings.TrimSpace(*in.NickName)) > 0 {
		afterSaleRequest.NickName = *in.NickName
	}
	if in.RefundType != nil && *in.RefundType > 0 {
		afterSaleRequest.RefundType = uint8(*in.RefundType)
	}
	if in.ReturnType != nil && *in.ReturnType > 0 {
		afterSaleRequest.ReturnType = uint8(*in.ReturnType)
	}
	if in.RefundAmount != nil && len(strings.TrimSpace(*in.RefundAmount)) > 0 {
		parseAmount, err := moneyx.ParseAmount(*in.RefundAmount)
		if err != nil {
			return nil, err
		}
		afterSaleRequest.RefundAmount = uint64(parseAmount)
	}
	if in.RefundDetails != nil && len(strings.TrimSpace(*in.RefundDetails)) > 0 {
		afterSaleRequest.RefundDetails = null.StringFrom(*in.RefundDetails)
	}
	if in.Remark != nil && len(strings.TrimSpace(*in.Remark)) > 0 {
		afterSaleRequest.Remark = null.StringFrom(*in.Remark)
	}
	now := time.Now()
	afterSaleRequest.CreatedAt = now
	afterSaleRequest.UpdatedAt = now
	var media []*model.AttachmentRelationship
	if len(in.Media) > 0 {
		afterSaleRequest.WithAfterSaleImage = 1
		for idx, v := range in.Media {
			var url string
			if v.Url != nil && len(*v.Url) > 0 { // v.Uri  content版本（包含?id）  v.Url  url当前版本 | attachment当前版本
				url = *v.Url
			}
			if len(url) == 0 && v.Uri != nil && len(*v.Uri) > 0 {
				url = *v.Uri
			}
			if len(url) == 0 {
				continue
			}
			var thumbnail uint8
			if v.Thumbnail != nil && *v.Thumbnail > 0 {
				thumbnail = uint8(*v.Thumbnail)
			}
			var order uint
			if v.Order != nil {
				order = uint(*v.Order)
			} else {
				order = uint(idx) + globalkey.AttachmentOrderOffset
			}
			var altText string
			if v.AltText != nil && len(*v.AltText) > 0 {
				altText = *v.AltText
			}
			var meta []string
			if v.Name != nil && len(*v.Name) > 0 {
				meta = append(meta, "filename:"+*v.Name)
				if len(altText) == 0 {
					altText = *v.Name
				}
			}
			if v.MetaData != nil && len(*v.MetaData) > 0 {
				meta = append(meta, *v.MetaData)
			}
			if v.MimeType != nil && len(*v.MimeType) > 0 {
				meta = append(meta, "mimeType:"+*v.MimeType)
			}

			var metaData string = strings.Join(meta, ";")
			var mediaId uint64
			if v.Id != nil && len(*v.Id) > 0 {
				if i, err := strconv.ParseInt(*v.Id, 10, 64); err == nil {
					mediaId = uint64(i)
				}
			}

			if mediaId > 0 { // mediaId > 0 不是外链
				media = append(media, &model.AttachmentRelationship{
					AttachmentID:        mediaId,
					AttachmentThumbnail: thumbnail,
					AttachmentOrder:     order,
					AttachmentImageURL:  url,
					AttachmentImageAlt:  altText,
					AttachmentImageMeta: metaData,
				})
			} else {
				media = append(media, &model.AttachmentRelationship{
					AttachmentThumbnail: thumbnail,
					AttachmentOrder:     order,
					AttachmentImageURL:  url,
					AttachmentImageAlt:  altText,
					AttachmentImageMeta: metaData,
				})
			}

		}
	}

	err := l.svcCtx.AfterSaleRequest.Insert(l.ctx, nil, &afterSaleRequest, &model.AfterSaleRequestRel{
		Media: media,
	})
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	return &order.BaseIDResp{
		Id:  afterSaleRequest.ID,
		Msg: i18n.CreateSuccess,
	}, nil
}
